/**********************************************************************
 * Filename: CalendarDate.java
 * Created: 2012/04/23
 * @author Fernando Brito e Abreu
 **********************************************************************/
package iscte.es.copaPaises.businessLayer;

import java.util.Set;
import java.util.HashSet;

public class CalendarDate
{
	public static Set<CalendarDate> allInstances = new HashSet<CalendarDate>();

	private int day;
	private int month;
	private int year;

	/**********************************************************************
	 * Default constructor
	 **********************************************************************/
	public CalendarDate()
	{
		allInstances.add(this);
	}

	/**********************************************************************
	 * Parameterized constructor
	 * @param day the day to initialize
	 * @param month the month to initialize
	 * @param year the year to initialize
	 **********************************************************************/
	public CalendarDate(int day, int month, int year)
	{
		this.day = day;
		this.month = month;
		this.year = year;
		allInstances.add(this);
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the day of the calendarDate
	 **********************************************************************/
	
	public void destroy(){
	allInstances.remove(this);	
	}
	
	
	public int day()
	{
		return day;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param day the day to set
	 **********************************************************************/
	public void setDay(int day)
	{
		this.day = day;
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the month of the calendarDate
	 **********************************************************************/
	public int month()
	{
		return month;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param month the month to set
	 **********************************************************************/
	public void setMonth(int month)
	{
		this.month = month;
	}

	/**********************************************************************
	 * Standard attribute getter
	 * @return the year of the calendarDate
	 **********************************************************************/
	public int year()
	{
		return year;
	}

	/**********************************************************************
	 * Standard attribute setter
	 * @param year the year to set
	 **********************************************************************/
	public void setYear(int year)
	{
		this.year = year;
	}


	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param date the date to set
	 **********************************************************************/
	public void initS(String date)
	{
		//	DONE
		this.year = Integer.parseInt(date.substring(0,4));
		this.month = Integer.parseInt(date.substring(5,7));
		this.day = Integer.parseInt(date.substring(8,10));
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public boolean isAfter(CalendarDate t)
	{
		
		//DONE
		if(this.year==t.year){
			if(this.month==t.month){
				if(this.day>t.day)
					return true;
			}else{
				if(this.month>t.month){
					return true;	
				}
			}
		}else{
			if(this.year>t.year){
				return true;
			}
		}
		//	return if (self.year = t.year) then if (self.month = t.month) then (self.day > t.day) else (self.month > t.month) endif else (self.year > t.year) endif
		return false;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public boolean isBefore(CalendarDate t)
	{
		//	DONE
		if(this.year==t.year){
			if(this.month==t.month){
				if(this.day<t.day)
					return true;
			}else{
				if(this.month<t.month){
					return true;	
				}
			}
		}else{
			if(this.year<t.year){
				return true;
			}
		}
		//	return if (self.year = t.year) then if (self.month = t.month) then (self.day < t.day) else (self.month < t.month) endif else (self.year < t.year) endif
		return false;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param x the x to set
	 * @param y the y to set
	 **********************************************************************/
	public boolean isDivisible(int x, int y)
	{
		//	DONE
		if(((x/y)*y)==x){
			return true;
		}
		//	return (((x div y) * y) = x)
		return false;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public boolean isEqual(CalendarDate t)
	{
		//	DONE
		return(this.year==t.year&&this.month==t.month &&this.day==t.day);
		//	return (((self.year = t.year) and (self.month = t.month)) and (self.day = t.day))

	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 **********************************************************************/
	public boolean isLeap()
	{
		//	DONE
		if(this.isDivisible(this.year, 400)){
			return true;
		}else{
			if(this.isDivisible(this.year,100)){
				return false;
			}else{
				if(this.isDivisible(this.year, 4)){
					return true;
				} 
			}
		}
		return false;
		//	return if (self.isDivisible(self.year, 400) or self.isDivisible(self.year, 4)) then true else if self.isDivisible(self.year, 100) then false else if self.isDivisible(self.year, 4) then true else false endif endif endif

	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param date the date to set
	 **********************************************************************/
	public CalendarDate stringToDate(String date)
	{
		//	DONE
		Integer date_year = Integer.parseInt(date.substring(0,4));
		Integer date_month = Integer.parseInt(date.substring(5,7));
		Integer date_day = Integer.parseInt(date.substring(8,10));
		CalendarDate result=null;
		for(CalendarDate d:CalendarDate.allInstances){
			if(d.year==date_year&&d.month==date_month&&d.day==date_day){
				result=d;
			}
		}
		
		if(result==null){
			result=new CalendarDate(date_day,date_month,date_year);
		}
		return result;



		//	 result := CalendarDate.allInstances->select(cd : CalendarDate | (((cd.year = date_year.toInteger) and (cd.month = date_month.toInteger)) and (cd.day = date_day.toInteger)))->asSequence->first;
		//	 if result.isUndefined then result := new CalendarDate(((('D' + date_year) + date_month) + date_day));
		//	 result.initS(date) end;
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 **********************************************************************/
	public String toString()
	{
		//DONE
		String month_S="";
		String day_S="";

		if(this.month<10){
			month_S="-0"+this.month;
		}else{
			month_S="-"+this.month;
		}
		if(this.day<10){
			day_S="-0"+this.day;
		}else{
			day_S="-"+this.day;
		}

		return (this.year()+month_S+day_S);
		//	return if ((self.month < 10) and (self.day < 10)) then ((((self.year.toString + '-0') + self.month.toString) + '-0') + self.day.toString) else if ((self.month < 10) and (self.day > 9)) then ((((self.year.toString + '-0') + self.month.toString) + '-') + self.day.toString) else if ((self.month > 9) and (self.day < 10)) then ((((self.year.toString + '-') + self.month.toString) + '-0') + self.day.toString) else ((((self.year.toString + '-') + self.month.toString) + '-') + self.day.toString) endif endif endif
	}

	/**********************************************************************
	 * User-defined operation specified in SOIL/OCL
	 * @param t the t to set
	 **********************************************************************/
	public int yearsSince(CalendarDate t)
	{
		//	DONE
		int result=-1;

		if(this.month<t.month|| (this.month==t.month && this.day<t.day)){
			result= this.year-t.year-1;
		}else{
			result=this.year-t.year;
		}
		return result;
		//	return if ((self.month < t.month) or ((self.month = t.month) and (self.day < t.day))) then ((self.year - t.year) - 1) else (self.year - t.year) endif
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */

	/**********************************************************************
	 * Object serializer
	 **********************************************************************/
	//public String toString()
	//{
	//return "CalendarDate [day=" + day + ", month=" + month + ", year=" + year + "]\n";
	//}

}
